package com.test.study.discovery;

import com.google.common.collect.Lists;
import com.test.study.loadblance.RandomLoadBlance;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;

import java.util.List;

/**
 * @ClassName AbstractDiscovery
 * @Description TODO
 * @Author USER
 * @Date 2019/7/12 15:58
 * @Company
 **/
public class DiscoveryWithZk implements IDiscovery {

    public static final String CONNECT_URL="192.168.137.184:2181," +
            "192.168.137.237:2181,192.168.137.143:2181";
    public static final String PROJECT_NAME="registry";

    List<String> serviceRepos = Lists.newArrayList();

    CuratorFramework curatorFramework;
    {
        curatorFramework = CuratorFrameworkFactory.builder().connectString(CONNECT_URL)
                .retryPolicy(new ExponentialBackoffRetry(1000,3))
                .sessionTimeoutMs(5000).namespace
                        (PROJECT_NAME)
                .build();
        curatorFramework.start();
    }

    /**
     * Title
     * @Author zj
     * @Date 2019/7/12 16:01
     * @Param serviceName
     * @Return java.lang.String
     */
    @Override
    public String discovery(String serviceName) {
        //服务查找
        String servicePath = "/"+serviceName;
        try {
            // 获取服务列表
            serviceRepos = curatorFramework.getChildren().forPath(servicePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //服务监听，动态感知
        try {
            addChildWatcher(curatorFramework,servicePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        RandomLoadBlance randomLoadBlance = new RandomLoadBlance();
        return randomLoadBlance.selectService(serviceRepos);
    }

    public void addChildWatcher(CuratorFramework curatorFramework,String path)
            throws Exception {
        //创建该节点的监听节点
        PathChildrenCache nodeCache = new PathChildrenCache(
                curatorFramework, "/watcher", false);
        //创建Listener
        PathChildrenCacheListener listener = (curatorFramework1, pathChildrenCacheEvent)->{
           //动态感知，所以要重新获取
            serviceRepos = curatorFramework1.getChildren().forPath(path);

        };
        // 注册Listener
        nodeCache.getListenable().addListener(listener);
        //启动watcher
        //
        nodeCache.start(PathChildrenCache.StartMode.NORMAL);

    }
}
